﻿#include "GraphicsTool/Thread_pool.h"

#include <fstream>
#include <future>

ThreadPool::ThreadPool(size_t threads) : m_threads(std::vector<std::thread>(threads)), m_shutdown(false)
{

}
ThreadPool::~ThreadPool()
{

}

void multiply(int a, int b)
{
	int res = a * b;
	std::cout << res << std::endl;
}

void multiply_output(int a, int b)
{
	int res = a * b;
	std::cout << res << std::endl;
}

void example()
{
	ThreadPool pool(3);
	pool.init();

	for (size_t i = 1; i <= 3; ++i)
	{
		for (size_t j = 1; j <= 10; ++j)
		{
			pool.subimit(multiply, i, j);
		}
	}
}

std::mutex mtx; // 创建互斥锁对象
std::condition_variable cv; // 创建条件变量对象
int count = 0; // 记录已经到达栅栏的线程数目
const int numThreads = 3; // 设置需要参与栅栏的线程数目


void barrier()
{
	std::unique_lock<std::mutex> lock(mtx);
	count++;

	if (count == 3)
	{
		count = 0;
		cv.notify_all();
	}
	else
	{
		cv.wait(lock);
	}
}

// 定义一些虚构的任务函数
void taskFunctionA() {
	for (int i = 0; i < 3; ++i) {
		std::cout << "Task A is running." << std::endl;
		barrier(); // 进入栅栏
	}
}

void taskFunctionB() {
	for (int i = 0; i < 2; ++i) {
		std::cout << "Task B is running." << std::endl;
		barrier(); // 进入栅栏
	}
}

int Test(int i)
{
 std::cout << i;
	 return i;
}

class TPool
{
public:
	void Run()
	{
		while (true)
		{
			popTask();

			std::unique_lock<std::mutex> loc(mMutex);
			if (mqueue.empty())
			{
				mConditional.wait(loc);
			}
		}
	}

	~TPool()
	{
		for (size_t i = 0; i < 5; i++)
		{
			if (mThreads[i].joinable())
			{
				mThreads[i].join();
			}
			
		}
	}
	void init(int numThreads)
	{
		for (size_t i = 0; i < numThreads; i++)
		{
			mThreads.push_back(std::thread(&TPool::Run, this));
		}
	}

	void pushTask(std::function<int(int)>& task)
	{
		std::unique_lock<std::mutex> loc(mMutex);
		mqueue.push(std::move(task));
		mConditional.notify_all();
	}

	void popTask()
	{
		std::unique_lock<std::mutex> loc(mMutex);

		if (!mqueue.empty())
		{
			std::function<int(int)> task = std::move(mqueue.front());
			mqueue.pop();

			task(3);
		}

	}

	void shutdown()
	{
		mConditional.notify_all();

		for (int i = 0; i < mThreads.size(); ++i)
		{
			if (mThreads.at(i).joinable())
			{
				mThreads.at(i).join();
			}
		}

	}

public:
	std::queue<std::function<int(int)>> mqueue;

	std::mutex mMutex;

	std::mutex mQueuemMutex;

	std::condition_variable mConditional;

	std::vector<std::thread> mThreads;

};

//A,B,C按照顺打印

void print1(std::ofstream& ofs)
{
	for (size_t i = 0; i < 100; i++)
	{
		std::unique_lock<std::mutex> lock(mtx);
		ofs << "A" << std::endl;
		barrier();
	}

}

void print2(std::ofstream& ofs)
{
	for (size_t i = 0; i < 100; i++)
	{
		ofs << "B" << std::endl;
		barrier();
	}
}

void print3(std::ofstream& ofs)
{
	for (size_t i = 0; i < 100; i++)
	{
		ofs << "C" << std::endl;
		barrier();
	}
}

class cdequeue
{
public:
	std::mutex mutex;
	std::queue<std::function<void(std::ofstream&, std::string)>> mdeque;
public:
	void push(std::function<void(std::ofstream&, std::string)> fun)
	{
		std::unique_lock<std::mutex> lock(mutex);
		mdeque.push(fun);
	}

	std::function<void(std::ofstream&, std::string)> pop()
	{
		std::unique_lock<std::mutex> lock(mutex);

		std::function<void(std::ofstream&, std::string)> t = mdeque.front();

		mdeque.pop();

		return t;
	}
};

//生产者，消费者
//三个线程同步

void printxx(std::ofstream& ofs, std::string n)
{
	ofs << n.c_str()<<std::endl;
}



class Pool
{
public:

	Pool()
	{
		for (size_t i = 0; i < 3; i++)
		{
			mSummer.push_back(std::thread(&Pool::subTask, this));
		}
	}
	~Pool(){}

public:

	

	void init()
	{
		for (size_t i = 0; i < 100; i++)
		{
			std::unique_lock<std::mutex> mt;
			if (mdequeue.mdeque.size() < 10)
			{
				std::function<void(std::ofstream&, std::string)> s = printxx;
				mdequeue.push(s);
			}
			else
			{
				mcd.notify_all();
				mcd.wait(mt);
			}
		}
	}

	void subTask()
	{
		while (true)
		{
			std::unique_lock<std::mutex> mt;
			if (!mdequeue.mdeque.empty())
			{
				
				std::function<void(std::ofstream&, std::string)> t = mdequeue.pop();
				t(mofs, "a");
			}
			else
			{
				mcd.notify_all();
				mcd.wait(mt);
			}
		}
	}

public:
	std::vector< std::thread > mCreate;
	std::vector<std::thread> mSummer;

	std::mutex mtext;
	std::condition_variable mcd;

	cdequeue mdequeue;

	std::ofstream mofs;
};

class Barer
{
public:
	std::thread t1, t2, t3;

	Barer(std::ofstream& ofs)
	{
		t1 = std::thread(print1, std::ref(ofs));
		t2 = std::thread(print2, std::ref(ofs));
		t3 = std::thread(print3, std::ref(ofs));

		t1.join();
		t2.join();
		t3.join();
	}

	void print()
	{

	}
};





void ThreadPool::test_thread_pool()
{
	std::vector<std::thread> threads;

	//// 创建两个线程分别运行taskFunctionA和taskFunctionB
	threads.push_back(std::thread(taskFunctionA));
	threads.push_back(std::thread(taskFunctionB));

	//// 等待所有线程结束
	for (auto& thread : threads) {
		thread.join();
	}
	




	//TPool pl;


	//for (size_t i = 0; i < 200; i++)
	//{
	//	std::function<int(int)> t = Test;
	//	pl.pushTask(t);
	//}

	//pl.init(5);
	
	return;
}


